home *** CD-ROM | disk | FTP | other *** search
/ Network CD 1 / Network CD.iso / photocd / opalvision / opalpcd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-10  |  36.9 KB  |  1,326 lines

  1. /* opalpcd.c v0.15
  2.        program to display PhotoCD  pictures and save them to OpalVision
  3.    files and display.  This will read the file and convert it to a 
  4.    virtual screen which may be saved in a JPEG or IFF24 file.
  5.    
  6.    
  7.    This program is based on hpcdtoppm by Hadmut Danisch  
  8.    
  9.    OH Yeah, Its going to take helluva lotta memory 
  10.                        base =1.5m, 4base=6meg, 16base =24m 
  11.                        Picked up and adapted by BAZZ on 3-2-93
  12. I will have to use RGB toOV, and may have to break it up into
  13.  several modules to save RAM. 
  14.  
  15.     Additions © BAZZ 1993, and similar conditions as Hadmut states apply, that
  16. is pass it around all you want, but dont take credit for it (unless you 
  17. add to it) and don't distribute for profit.  This is intended to enrich the 
  18. Amiga community and is for educational purposes only.
  19.  
  20.     
  21.     As of 3-8 I had resolutions up thru Base working.  The decompression isnt
  22. working right on 4Base and is being looked into.  This will print out on an
  23. OpalVision screen.  The library should allown IFF24 conversion and is included
  24. with many utilities.  It might work without it but not guaranteed.    
  25.        
  26.        
  27.                */
  28.  
  29.  
  30.  
  31.  
  32. /* hpcdtoppm (Hadmut's pcdtoppm) v0.1
  33. *  Copyright (c) 1992 by Hadmut Danisch (danisch@ira.uka.de).
  34. *  Permission to use and distribute this software and its
  35. *  documentation for noncommercial use and without fee is hereby granted,
  36. *  provided that the above copyright notice appear in all copies and that
  37. *  both that copyright notice and this permission notice appear in
  38. *  supporting documentation. It is not allowed to sell this software in 
  39. *  any way. This software is not public domain.
  40. */
  41.  
  42.  
  43.  
  44.  
  45. #define xDEBUG
  46. /* extern char *malloc(); */
  47.  
  48. #include <proto/all.h>
  49. #include <opal/opallib.h>
  50. #include <graphics/gfxbase.h>
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <String.h>
  54. #include <intuition/intuition.h>
  55. #include <intuition/intuitionbase.h>
  56. #include <libraries/asl.h>
  57. #include <exec/execbase.h>
  58. #include <graphics/gfxmacros.h>
  59. #include <devices/timer.h>
  60. #include <workbench/startup.h>
  61. #include <time.h>
  62.  
  63. #include <math.h>  /* lets give it something to REALLY Render */
  64. #include <m68881.h> /* use co pro wherever possible */
  65.  
  66. typedef unsigned char byte; /* really UBYTE */
  67. typedef unsigned long dim;
  68.  
  69. #define BaseW ((dim)768)
  70. #define BaseH ((dim)512)
  71.  
  72. #define   DISP_W   736
  73. #define   DISP_H   476 /* hi-res screen */ 
  74.  
  75.  
  76. #define slen 3072 /* try to keep all defines here! */
  77.  
  78.  
  79. #define SECSIZE 0x800 /* 2k for CDrom */
  80.  
  81.  
  82. #define ASKIP { argc--; argv ++;}
  83.  
  84. #define SeHead   2
  85. #define L_Head   (1+SeHead)
  86.  
  87. #define SeBase16 18
  88. #define L_Base16 (1+SeBase16)
  89.  
  90. #define SeBase4  72
  91. #define L_Base4  (1+SeBase4)
  92.  
  93. #define SeBase   288
  94. #define L_Base   (1+SeBase)
  95. #define S_DEFAULT S_Base  /* default to base */
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102. enum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF,
  103.                                                            E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,
  104.                                                            E_IMP,E_COOL,E_OVD,E_SCR,E_NCDS };
  105.  
  106. enum TURNS  { T_NONE,T_RIGHT,T_LEFT };
  107.  
  108. enum SIZES  { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_Over };
  109.  
  110. /* Default taken when no size parameter given */
  111.  
  112.  
  113.  
  114. struct ph1 /* the header for the Photo CD file */
  115.  {char id1[8];
  116.   char ww1[14];
  117.   char id2[20];
  118.   char id3[4*16+4];
  119.   short ww2;
  120.   char id4[20];
  121.   char ww3[2*16+1];
  122.   char id5[4*16];
  123.   char idx[11*16];
  124.  } ;
  125.  
  126.  
  127. struct _implane
  128.  {dim  mwidth,mheight,
  129.              iwidth,iheight;
  130.   byte *im;
  131.  };
  132. typedef struct _implane implane;
  133.  
  134. /* PROTOTYPES */
  135. void    cleanup(enum ERRORS);
  136. void    telltime( unsigned long *);
  137. int Display_Mode_Check(void);
  138. int DoOpal(int,int, char *fname);
  139. int GetNextPic(int,int);
  140. int TurnOpal( struct OpalScreen *, UBYTE **, int,int,int,int,int);
  141.  
  142. static void planealloc(implane *,dim,dim);
  143.  
  144. static void interpolate(implane *);
  145. static void ycctorgb(dim,dim, implane *,implane *,implane *);
  146. static void readlpt(dim,dim);
  147. static void readhqt(dim,dim,dim);
  148. static void readhqtsub(struct pcdhqt *source,struct myhqt *ziel,int *anzahl);
  149.  
  150.  
  151. static void decompress(dim,dim,implane *,implane *, implane *);
  152. static void clear(implane *,int);
  153. static void druckeid(void );
  154. static void sharpit(implane *);
  155. enum ERRORS readplain(dim,dim,implane *,implane *,implane*);
  156.  
  157. /* Global Variables */
  158. struct IntuitionBase *IntuitionBase;
  159. struct GfxBase *GfxBase;
  160. struct OpalBase *OpalBase;
  161. struct OpalScreen *OScrn;
  162. struct WBArg *WBArg;
  163. BOOL FromWB;
  164.  
  165. __far UBYTE *Button = (UBYTE *)0xbfe001;    /* Nasty */
  166.  
  167. static FILE *fin=0,*fout=0;
  168. static char *pcdname=0,*ppmname=0;
  169. static char nbuf[100];
  170. static byte sbuffer[SECSIZE];
  171. static int do_sharp,backdrop;
  172. implane Luma, Chroma1,Chroma2; /* make them global */
  173. dim w,h;
  174. unsigned long clock1[2],clock2[2]; /* for timer */
  175.  enum TURNS turn=T_NONE;
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182. /* Using preprocessor for inline-procs */
  183. #ifdef DEBUG
  184. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) cleanup(E_READ);\
  185.                   fprintf(stderr,"S-Position %x\n",ftell(fin)); }
  186. #else
  187. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) cleanup(E_READ);}
  188. #endif
  189.  
  190.  
  191. #define SKIP(n)  { if (fseek(fin,(n),1)) cleanup(E_READ);}
  192. #define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
  193.  
  194. #define READBUF   fread(sbuffer,sizeof(sbuffer),1,fin)
  195.  
  196. #define TRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b)  ))
  197. #define NORM(x) x=TRIF(x,0,255,0,x,255)
  198.  
  199.  
  200.  
  201.  
  202. void cleanup(e)  /* leave and display why */
  203. enum ERRORS e;
  204. {
  205.   
  206.   switch(e)
  207.    {case E_NONE:   return;
  208.     case E_IMP:    fprintf(stderr,"Sorry, Not yet implemented.\n"); break;
  209.     case E_READ:   fprintf(stderr,"Error while reading.\n"); break;
  210.     case E_WRITE:  fprintf(stderr,"Error while writing.\n"); break;
  211.     case E_INTERN: fprintf(stderr,"Internal error.\n"); break;
  212.     case E_ARG:    fprintf(stderr,"Arguments !\n"); 
  213.                    fprintf(stderr,"OpalPCD Access for Amiga \n");
  214.                    fprintf(stderr,"Usage: opalpcd [options] pcd-file [IFF24file]\n");
  215.                    fprintf(stderr,"Opts:\n");
  216.                    fprintf(stderr,"     -i Give some (buggy) informations from fileheader\n");
  217.                    fprintf(stderr,"     -s Apply simple sharpness-operator on the Luma-channel\n");
  218.                    fprintf(stderr,"     -d Show differential picture only \n");
  219.                    fprintf(stderr,"     -r Rotate clockwise for portraits\n");
  220.                    fprintf(stderr,"     -l Rotate counter-clockwise for portraits\n");
  221.                    fprintf(stderr,"     -a Enable AutoSync for Opal Display  \n");
  222.                    fprintf(stderr,"     -p Presentation SLideShow all Images in cd0:\n");
  223.                    fprintf(stderr,"     -b To place image as backdrop upon exit \n"); 
  224.  
  225.                    fprintf(stderr,"     -0 Extract thumbnails from Overview file\n");
  226.                    fprintf(stderr,"     -1 Extract  128x192  from Image file\n");
  227.                    fprintf(stderr,"     -2 Extract  256x384  from Image file\n");
  228.                    fprintf(stderr,"     -3 Extract  512x768  from Image file\n");
  229.                    fprintf(stderr,"     -4 Extract 1024x1536 from Image file\n");
  230.                    fprintf(stderr,"     -5 Extract 2048x3072 from Image file\n");
  231.                    break;
  232.     case E_OPT:    fprintf(stderr,"These Options are not allowed together.\n");break;
  233.     case E_MEM:    fprintf(stderr,"Not enough memory !\n"); break;
  234.     case E_HUFF:   fprintf(stderr,"Error in Huffman-Code-Table\n"); break;
  235.     case E_SEQ:    fprintf(stderr,"Error in Huffman-Sequence\n"); break;
  236.     case E_SEQ1:    fprintf(stderr,"Error1 in Huffman-Seque nce\n"); break;
  237.     case E_SEQ2:    fprintf(stderr,"Error2 in Huffman-Sequence\n"); break;
  238.     case E_SEQ3:    fprintf(stderr,"Error3 in Huffman-Sequence\n"); break;
  239.     case E_SEQ4:    fprintf(stderr,"Error4 in Huffman-Sequence\n"); break;
  240.     case E_SEQ5:    fprintf(stderr,"Error5 in Huffman-Sequence\n"); break;
  241.     case E_SEQ6:    fprintf(stderr,"Error6 in Huffman-Sequence\n"); break;
  242.     case E_SEQ7:    fprintf(stderr,"Error7 in Huffman-Sequence\n"); break;
  243.     case E_POS:    fprintf(stderr,"Error in file-position\n"); break;
  244.     case E_COOL:    fprintf(stderr,"Cannot opan opal.library \n"); break;
  245.      case E_OVD:    fprintf(stderr,"Opalvision error      \n"); break;
  246.      case E_SCR:    fprintf(stderr,"You need a 15KHZ scan rate(genlockable) screen  \n"); break;
  247.     case E_NCDS:     fprintf(stderr," Slide Show available in Base/4 and Base Only \n"); break;
  248.     
  249.     default:       fprintf(stderr,"Unknown error %d ???\n",e);break;
  250.    }
  251.   if(fin) fclose(fin); /* close files */
  252.   if(fout) fclose(fout);
  253.   if (OpalBase!=NULL) /* if we did play with OpalVision, lets fix things */
  254.         {   AmigaPriority();
  255.              CloseScreen24 ();
  256.           CloseLibrary ((struct Library *)OpalBase);
  257.    }
  258.  
  259.   exit(e); /* return the error */
  260. }
  261.  
  262.  
  263. static void planealloc(p,width,height)
  264.   implane *p;
  265.   dim width,height;
  266.  {
  267.   p->iwidth=p->iheight=0;
  268.   p->mwidth=width;
  269.   p->mheight=height;
  270.     /* this is level II and freed by c startup, we should fix later */
  271.   p->im = ( byte * ) malloc  (width*height);/* we know a byte is 1! */
  272.   if(!(p->im)) cleanup(E_MEM);
  273.  }
  274.  
  275.  
  276.  
  277.  
  278.  
  279. main(argc,argv)  /* MAIN  */
  280. int argc;
  281. char **argv;
  282. {int i,bildnr;
  283. char *opt;
  284. int do_auto,cd_offset,do_info,do_diff,do_overskip,do_slide;
  285.  
  286.        enum SIZES size=S_UNSPEC;
  287.     enum ERRORS eret;
  288.      do_info=do_auto=do_diff=do_overskip=do_sharp=0; 
  289.     backdrop=do_slide=0;
  290.     Luma.im=Chroma1.im=Chroma2.im = NULL;
  291.      ASKIP;
  292.         /* parse input line */
  293.     while((argc>0) && **argv=='-') {
  294.          opt= (*argv)+1;
  295.         ASKIP;
  296.  
  297.         if(!strcmp(opt,"a")) /* slide show mode */
  298.             {if (!do_auto ) do_auto=255;
  299.             else cleanup(E_ARG);
  300.             continue;
  301.             }
  302.  
  303.  
  304.         if(!strcmp(opt,"p")) /* slide show mode */
  305.             {if (!do_slide ) do_slide=255;
  306.             else cleanup(E_ARG);
  307.             continue;
  308.             }
  309.  
  310.  
  311.         if(!strcmp(opt,"r"))
  312.             {if (turn == T_NONE) turn=T_RIGHT;
  313.             else cleanup(E_ARG);
  314.             continue;
  315.             }
  316.  
  317.         if(!strcmp(opt,"l"))
  318.             {if (turn == T_NONE) turn=T_LEFT;
  319.             else cleanup(E_ARG);
  320.             continue;
  321.             }
  322.  
  323.         if(!strcmp(opt,"i")) 
  324.             { if (!do_info) do_info=1;
  325.             else cleanup(E_ARG);
  326.             continue;
  327.             }
  328.  
  329.  
  330.         if(!strcmp(opt,"d")) 
  331.             { if (!do_diff) do_diff=1;
  332.             else cleanup(E_ARG);
  333.             continue;
  334.             }
  335.           if(!strcmp(opt,"b")) 
  336.             { if (!backdrop) backdrop=1;
  337.             else cleanup(E_ARG);
  338.             continue;
  339.             }
  340.  
  341.         if(!strcmp(opt,"s")) 
  342.             { if (!do_sharp) do_sharp=1;
  343.             else cleanup(E_ARG);
  344.             continue;
  345.             }
  346.  
  347.  
  348.         if(!strcmp(opt,"x")) 
  349.             { if (!do_overskip) do_overskip=1;
  350.             else cleanup(E_ARG);
  351.             continue;
  352.             }
  353.  
  354.  
  355.  
  356.    /* get desired size */
  357.         if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1"))  || (!strcmp(opt,"128x192")))
  358.           {  if (size == S_UNSPEC) size = S_Base16;
  359.             else cleanup(E_ARG);
  360.             continue;
  361.         }
  362.         if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2"))  || (!strcmp(opt,"256x384")))
  363.             { if (size == S_UNSPEC) size = S_Base4;
  364.             else cleanup(E_ARG);
  365.             continue;
  366.         }
  367.         if((!strcmp(opt,"Base"   )) || (!strcmp(opt,"3"))  || (!strcmp(opt,"512x768")))
  368.             { if (size == S_UNSPEC) size = S_Base;
  369.             else cleanup(E_ARG);
  370.             continue;
  371.         }
  372.         if((!strcmp(opt,"4Base"  )) || (!strcmp(opt,"4"))  || (!strcmp(opt,"1024x1536")))
  373.             { if (size == S_UNSPEC) size = S_4Base;
  374.             else cleanup(E_ARG);
  375.              continue;
  376.         }
  377.         if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5"))  || (!strcmp(opt,"2048x3072")))
  378.         { if (size == S_UNSPEC) size = S_16Base;
  379.             else cleanup(E_ARG);
  380.             continue;
  381.             }
  382.  
  383.         if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0"))  || (!strcmp(opt,"O")))
  384.             { if (size == S_UNSPEC) size = S_Over;
  385.             else cleanup(E_ARG);
  386.             continue;
  387.             }
  388.  
  389.         fprintf(stderr,"Unknown option: -%s\n",opt);
  390.             cleanup(E_ARG);
  391.         }
  392.  
  393.  
  394.  
  395.  
  396.   if(size==S_UNSPEC) size=S_DEFAULT;
  397.  
  398.   if((argc<1) && !(do_slide)) cleanup(E_ARG); /* forgive lack of name if slide */
  399.   if ( !(do_slide))pcdname= *argv;
  400.     ASKIP;
  401.  
  402.   if(argc>0) 
  403.    {ppmname= *argv;
  404.     ASKIP;
  405.    }
  406.   
  407.   if(argc>0) cleanup(E_ARG);
  408.   if((size==S_Over) && (!ppmname)) cleanup(E_ARG);
  409.   if(do_info && (size==S_Over)) cleanup(E_OPT);
  410.   if(do_diff && (size != S_4Base) && (size != S_16Base)) cleanup(E_OPT);
  411.   if(do_overskip) cleanup(E_IMP);
  412.   if(do_overskip && (size != S_Base4) && (size != S_Base16)) cleanup(E_OPT);
  413.   if(do_slide) { /* for auto */
  414.        
  415.       ppmname=NULL; /* we wont save file */
  416.       pcdname="CD0:PHOTO_CD/IMAGES/IMG0001.PCD"; /* the first on any disk */
  417.       if (size > S_Base) {
  418.             printf( "can't slideshow above base res \n");
  419.             cleanup(E_ARG);    }      
  420.    }
  421.  
  422.  
  423. #ifdef DEBUG
  424. fprintf(stderr,"Turn %d  Size %d Pcd %s  ppm %s\n",turn,size,pcdname,ppmname);
  425. #endif
  426.  
  427.   if(!(fin=fopen(pcdname,"r"))) cleanup(E_READ);
  428.   if(do_info) druckeid(); /* show ID code */
  429.     OpalBase = (struct OpalBase *) OpenLibrary ("opal.library",0L);
  430.     if (OpalBase==0L) /* opal opal library */
  431.         cleanup (E_COOL);
  432.     OScrn = NULL;
  433.   i=timer(clock1); /* get clock */
  434.  
  435.   switch(size) /* perform the operation based on size */
  436.    {
  437.     case S_Base16: w=BaseW/4;
  438.                    h=BaseH/4;
  439.                    if (do_slide) cleanup( E_NCDS);
  440.  
  441.                    planealloc(&Luma   ,w,h);
  442.                    planealloc(&Chroma1,w,h);
  443.                    planealloc(&Chroma2,w,h);
  444.  
  445.                    SEEK(L_Head+1);
  446.                    cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  447.  
  448.                    interpolate(&Chroma1);
  449.                    interpolate(&Chroma2);
  450.  
  451.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  452.               /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  453.  
  454.              
  455.               /*     writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);*/
  456.                    DoOpal(do_auto,do_slide,ppmname);
  457.                    break;
  458.  
  459.     case S_Base4:  w=BaseW/2;
  460.                    h=BaseH/2;
  461.                    planealloc(&Luma   ,w,h);
  462.                    planealloc(&Chroma1,w,h);
  463.                    planealloc(&Chroma2,w,h);
  464.  
  465.                    SEEK(L_Head+L_Base16+1);
  466.                    cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  467.  
  468.                    interpolate(&Chroma1);
  469.                    interpolate(&Chroma2);
  470.  
  471.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  472.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  473.  
  474.                 /*     writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn); */
  475.                    DoOpal(do_auto,do_slide,ppmname);
  476.                    break;
  477.  
  478.     case S_Base:   w=BaseW;
  479.                    h=BaseH;
  480.             /*      printf("got base w %d h %d \n",w,h);  */
  481.                  
  482.                    planealloc(&Luma   ,w,h);
  483.                    planealloc(&Chroma1,w,h);
  484.                    planealloc(&Chroma2,w,h);
  485.            /*       printf("planes are allocated \n"); */
  486.                    SEEK(L_Head+L_Base16+L_Base4+1);
  487.                    cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  488.            /*     printf("plain is read \n"); */
  489.                    interpolate(&Chroma1);
  490.                    interpolate(&Chroma2);
  491.           /*      printf("interpolated \n"); */
  492.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  493.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  494.             /*    printf("converted to RGB \n"); */
  495.                   /*  writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn); */
  496.                 DoOpal( do_auto,do_slide,ppmname); /* do all the nice OpalVision stuff */
  497.                    break;
  498.  
  499.     case S_4Base:  w=BaseW*2;
  500.                    h=BaseH*2;
  501.                     if (do_slide) cleanup( E_NCDS);
  502.                    planealloc(&Luma,w,h);  /* thats almost 5 meg! */
  503.                    planealloc(&Chroma1,w,h);
  504.                    planealloc(&Chroma2,w,h);  
  505.  
  506.  
  507.                    SEEK(L_Head+L_Base16+L_Base4+1);
  508.                    cleanup(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  509.                    interpolate(&Luma);
  510.                    interpolate(&Chroma1);
  511.                    interpolate(&Chroma1);
  512.                    interpolate(&Chroma2);
  513.                    interpolate(&Chroma2);  
  514.  
  515.                    if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  516.                         /* above only clears */
  517.                    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  518.  
  519.                /*   SEEK(cd_offset + 3);   readlpt(w,h);  */ /* orig commentd out*/
  520.  
  521.                    SEEK(cd_offset + 4);     readhqt(w,h,1); 
  522.  
  523.                    SEEK(cd_offset + 5);     decompress(w,h,&Luma,0,0); 
  524.  
  525.  
  526.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);  
  527.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  528.                     telltime(clock1);
  529.  
  530.               /*    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);*/
  531.                    DoOpal( do_auto,do_slide,ppmname); /* try disp some */
  532.                    break;
  533.  
  534.     case S_16Base: w=BaseW*4;
  535.                    h=BaseH*4;
  536.               cleanup(E_IMP); /* not in yet */     
  537.                      if (do_slide) cleanup( E_NCDS);
  538.  
  539.                    planealloc(&Luma,w,h);
  540.                    planealloc(&Chroma1,w,h);
  541.                    planealloc(&Chroma2,w,h); 
  542.  
  543.                    SEEK(L_Head+L_Base16+L_Base4+1);
  544.                    cleanup(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
  545.                    interpolate(&Luma);
  546.                    interpolate(&Chroma1);
  547.                    interpolate(&Chroma1);
  548.                    interpolate(&Chroma2);
  549.                    interpolate(&Chroma2); 
  550.  
  551.  
  552.                    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  553.                    /*SEEK(cd_offset + 3);           
  554.                    readlpt(w/2,h/2);*/
  555.  
  556.                    SEEK(cd_offset + 4);             
  557.                    readhqt(w/2,h/2,1);
  558.  
  559.                    SEEK(cd_offset + 5);
  560.                    decompress(w/2,h/2,&Luma,0,0);
  561.                    interpolate(&Luma);
  562.  
  563.                    cd_offset=ftell(fin);
  564.                    if(cd_offset % SECSIZE) cleanup(E_POS);
  565.                    cd_offset/=SECSIZE;
  566.  
  567.                    SEEK(cd_offset+12);
  568.                    readhqt(w,h,3);
  569.  
  570.                    if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  571.  
  572.                    SEEK(cd_offset+14);
  573.                    decompress(w,h,&Luma,&Chroma1,&Chroma2);
  574.                    interpolate(&Chroma1);
  575.                    interpolate(&Chroma2);
  576.  
  577.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  578.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  579.  
  580.               /*     writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn); */
  581.  
  582.                    break;
  583.  
  584.     case S_Over:
  585.        w=BaseW/4;
  586.        h=BaseH/4;
  587.        
  588.        planealloc(&Luma   ,w,h);
  589.        planealloc(&Chroma1,w,h);
  590.        planealloc(&Chroma2,w,h);
  591.  
  592.        for(bildnr=0;!feof(fin);bildnr++){
  593.                SEEK(5+SeBase16*bildnr);
  594.     
  595.                eret=readplain(w,h,&Luma,&Chroma1,&Chroma2);
  596.                        if(eret==E_READ) break;
  597.                        cleanup(eret);
  598.  
  599.                interpolate(&Chroma1);
  600.                interpolate(&Chroma2);
  601.     
  602.                ycctorgb(w,h,&Luma,&Chroma1,&Chroma2); 
  603.                /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  604.        /*    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn); */
  605.                DoOpal(do_auto,0,ppmname);
  606.              }
  607.                    break;
  608.  
  609.      default: cleanup(E_INTERN); 
  610.    }
  611. exit(0); /* exit normal */
  612. }
  613.  
  614. #undef ASKIP
  615.  
  616.  
  617.  
  618. int DoOpal(int asy,int slide, char *fname) /* display and save OV */
  619.                                 /* use modes 2 and 3 only for now */
  620. {
  621. long scm,Err;
  622. int xos,yos,a,dw,dh,pic,slerr,orun;
  623. UBYTE *rgbp[4];
  624.     scm= OVERSCAN24;
  625.     pic=1; slerr=0; orun=1; /* init variables */
  626.     if (!Display_Mode_Check()) 
  627.         cleanup( E_SCR); /* check for 15KHZ res */
  628.     telltime(clock1);
  629.     dw= DISP_W/2; dh=DISP_H/2; 
  630.        if ( w> 400) {
  631.         scm |= ILACE24 | HIRES24; /* if base & up do hires lace */
  632.         dw=DISP_W; dh=DISP_H;
  633.  
  634.     }    
  635.     xos= (dw-w+2)/2; /* center picture */
  636.     yos= (dh-h+2)/2;
  637.      if ( w> 256) xos=yos=0; /* for this, dont lose res */  
  638.     if (w < 1000) {
  639.               if (turn){
  640.                 OScrn = CreateScreen24(scm,max(dw,h),max(dh,w)) ; 
  641.                              }  
  642.               else 
  643.                 OScrn = CreateScreen24(scm,max(dw,w),max(dh,h)) ; 
  644.                 /* same size virtual screen */
  645.             }
  646.     else {
  647.           xos=-300; yos=-200;
  648.  
  649.      /*   scm |= PLANES8 | PALMAP24 ; *//* mono test and save space */
  650.         OScrn = CreateScreen24(scm,500,320);
  651.       /* create just for disp to test higher mode */
  652.     }
  653.             
  654.     if ( !OScrn){
  655.         printf( "can't create Opal screen \n");
  656.          cleanup(E_OVD); }
  657.         /* create the virtual screen to plop the data in */
  658.    
  659.     /* below here updated for each pic, so loop on this ! */
  660.     while (orun && (pic < 150)) {  /* keep doing this */ 
  661.          rgbp[0]= Luma.im; /* set image area pointers */
  662.          rgbp[1]= Chroma1.im;
  663.          rgbp[2]= Chroma2.im;
  664.             TurnOpal(OScrn,rgbp,xos,yos,w,h,turn); /* turn it */
  665.              /* copy the data into the virtual screen */ 
  666.                AutoSync24(asy);
  667.          Err = (long)LowMemUpdate24 (OScrn,0);
  668.         if ((Err>OL_ERR_MAXERR) && (!(OScrn->Flags&ILACE24)))
  669.         {   AutoSync24 (asy);
  670.           /*  Err = (long)LowMemUpdate24 (OScrn,6); */
  671.         } 
  672.         if ( (OScrn) && (fname) ){ /* we can save file */
  673.             a=SaveIFF24(OScrn,fname, NULL,NULL); 
  674.             if (a) printf( "iff save error # %d couldn't save picture\n",a);
  675.             else printf( "file saved as %s \n",fname);
  676.         }  
  677.         
  678.         if (Err < OL_ERR_MAXERR)
  679.         { CloseScreen24 ();
  680.           if (Err==OL_ERR_OUTOFMEM)
  681.             printf ("Out of memory!! \n");
  682.           else if (Err==OL_ERR_CANTCLOSE)
  683.             printf("OpalVision Display in Use.\n");
  684.           else
  685.             printf("Error Displaying image!! \n");
  686.           cleanup(E_OVD);
  687.         }    
  688.         
  689.         pic++;
  690.         if (slide ) {
  691.            
  692.             slerr=GetNextPic(pic,0); 
  693.             if (slerr ==9) Delay(600); /* 10 sec hold on last pic */
  694.             if(slerr) orun=0; /* get the next file, if error,quit */
  695.          /*   FadeOut24(25);*/
  696.  
  697.         }
  698.         else orun=0;
  699.         OVPriority();   
  700.           Delay(10);
  701.           
  702.         if ( !(*Button & 0x040)) { /* button down for SLIDE */
  703.             Delay(30); /* debounse */
  704.             if (!(*Button & 0x040 )) orun=0; /* get out, is held down */
  705.         }
  706.               
  707.     } 
  708.      while ((*Button &0x040) && !(slide)){ /* button for single show */
  709.             Delay(10); }
  710.     if ( backdrop){ /* we want to leave image as backdrop */
  711.         AmigaPriority ();
  712.         DualDisplay24 ();
  713.         Delay (2L);
  714.         LatchDisplay24 (TRUE);
  715.         Delay (2L);
  716.     
  717.     }                    
  718.     FreeScreen24 (OScrn);
  719.     CloseScreen24(); 
  720.     return(0);    
  721. }                                    
  722.  
  723. int GetNextPic(int pic,int res) /* slidesow, get next picture to OV */
  724. {
  725. static char *fn="CD0:PHOTO_CD/IMAGES/IMG0001.PCD";
  726. int i,wm,ht;
  727.     if(fin) fclose(fin); /* if it is open, close it */
  728.     fin=NULL;
  729.     if((pic>199) || (pic<0)) return(999); /* pic too high */
  730.     wm=w/192; /* use to switch */
  731.     ht= (pic/100); /* convert to digits */
  732.     pic -= ht * 100; /* get it to 100 */
  733.     *(fn+24)= h+48; 
  734.  
  735.     *(fn+25)=(pic/10)+48;
  736.     *(fn+26)=(pic%10)+48;
  737.  /*   printf("filename is %s\n",fn); */
  738.     
  739.     fin=fopen(fn,"r");
  740.     if (!fin) return(9);
  741.     switch(wm) { /* based on resolution */
  742.         case 2 :    SEEK(L_Head+L_Base16+1); break;
  743.         case 4 :    SEEK(L_Head+L_Base16+L_Base4+1) ; break;
  744.         case 1 :    SEEK(L_Head+1); break;
  745.         default: return(13);
  746.     }
  747.     Luma.iwidth=Luma.iheight=0;
  748.     Chroma1.iwidth=Chroma1.iheight=0;
  749.     Chroma2.iwidth=Chroma2.iheight=0;
  750.     i=readplain(w,h,&Luma,&Chroma1,&Chroma2);
  751.     if (fin) { fclose(fin); fin=NULL; }
  752. /*     printf( "plane read %d w %d h %d i \n",w,h,i); */
  753.     if(i) return(i); /* an error here break */
  754.     interpolate(&Chroma1); 
  755.     interpolate(&Chroma2); 
  756.     ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  757.                     
  758.       return(0); /* successful */
  759. }
  760.  
  761. int TurnOpal( Oscr, rgbp, xos,yos,w,h,dir)
  762. struct OpalScreen *Oscr;
  763. UBYTE   *rgbp[3]; /* pointers for decoded Photo CD data */
  764. int xos,yos,w,h,dir; /* offset and size of image, and dir 0=no 1=r else l 
  765.         do cropping here, if unable to open screen, stash in file and 
  766.         reload down the line */
  767. {  /* this is to view images on edge.  To save memory we only buffer
  768.     16 lines */
  769. long size,lines;
  770. int i,j,ystep;
  771. UBYTE *buf,*rgbuf[3],*rp,*gp,*bp; /* pointers into array */
  772.     lines=16;
  773.     size=h*3*lines; /* well do 16 lines (initially columns ) at a time */
  774.     buf=malloc(size); /* try to allocate the memory */
  775.     rp=rgbuf[0]=buf;
  776.     gp=rgbuf[1]=buf+(h*lines);/* set pointer */
  777.     bp=rgbuf[2]=buf+(h*lines*2);
  778.     
  779.     if ( !buf) { 
  780.         printf("can't allocate turn buffer, try closing some windows \n");        
  781.         cleanup(E_MEM);
  782.     }
  783.     
  784.     if ( dir==0) { 
  785.         RGBtoOV ( OScrn,rgbp,xos,yos,w,h );
  786.         return(3); /* do this step here */ 
  787.     }
  788.     if (turn==1) { /* right turn */
  789.         /* start from bottom left j=column turned to row */
  790.         for(j=0; j<w; j++){   
  791.            for(i=h-1; i>=0; i--) { /* count up from bottom build one line*/
  792.                 ystep=(i*w)+j;
  793.                 *rp++=*(rgbp[0]+ ystep); /* copy pixels for each color */
  794.                 *gp++=*(rgbp[1]+ ystep);
  795.                 *bp++=*(rgbp[2]+ ystep);        
  796.            }
  797.            if(  ( ( j& 0x0F )==0x0f) || (j == w-1)) { /* update ea 16 lines*/
  798.                 rp=rgbuf[0]; /* eset pointers to bases */
  799.                 gp=rgbuf[1];
  800.                 bp=rgbuf[2];
  801.                 RGBtoOV( Oscr,rgbuf,xos,yos+j-lines+1,h,lines); /* convert it */
  802.            
  803.             }
  804.            
  805.         }
  806.      }   
  807.      else { /* left  turn */
  808.         /* start from bottom left j=column turned to row */
  809.         for(j=w-1; j>=0; j--){   
  810.            for(i=0; i<h; i++) { /* count down build one line*/
  811.                 ystep=(i*w)+j;
  812.                 *rp++=*(rgbp[0]+ ystep); /* copy pixels for each color */
  813.                 *gp++=*(rgbp[1]+ ystep);
  814.                 *bp++=*(rgbp[2]+ ystep);        
  815.            }
  816.            if(   ( j& 0x0F )==0x00) { /* update ea 16 lines*/
  817.                 rp=rgbuf[0]; /* reset pointers to bases */
  818.                 gp=rgbuf[1];
  819.                 bp=rgbuf[2];
  820.                 RGBtoOV( Oscr,rgbuf,xos,yos+w-j-lines,h,lines); /* convert it */
  821.            
  822.             }
  823.         }     
  824.      }
  825.      free(buf); /* let it go, we dont need it anymore */
  826.      return(j);
  827.  
  828.         
  829.  
  830. }
  831. enum ERRORS readplain(w,h,l,c1,c2)
  832. dim w,h;
  833. implane *l,*c1,*c2;
  834. {
  835. dim i;
  836. byte *pl=0,*pc1=0,*pc2=0;
  837.  
  838.   if(l)
  839.    { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) cleanup(E_INTERN);
  840.      l->iwidth=w;
  841.      l->iheight=h;
  842.      pl=l->im;
  843.    }
  844.  
  845.   if(c1)
  846.    { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) cleanup(0);
  847.      c1->iwidth=w/2;                    /* bypass for test only */
  848.      c1->iheight=h/2;
  849.      pc1=c1->im;
  850.    }
  851.  
  852.   if(c2)
  853.    { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) cleanup(0);
  854.      c2->iwidth=w/2;
  855.      c2->iheight=h/2;
  856.      pc2=c2->im;
  857.    }
  858.  
  859.   for(i=0;i<h/2;i++)
  860.    {
  861.     if(pl)
  862.      { 
  863.        if(fread(pl,w,1,fin)<1) return(E_READ);
  864.        pl+= l->mwidth;
  865.  
  866.        if(fread(pl,w,1,fin)<1) return(E_READ);
  867.        pl+= l->mwidth;
  868.      }
  869.     else SKIPr(2*w);
  870.      
  871.     if(pc1)
  872.      { if(fread(pc1,w/2,1,fin)<1) return(E_READ);
  873.        pc1+= c1->mwidth;
  874.      }
  875.     else SKIPr(w/2);
  876.      
  877.     if(pc2)
  878.      { if(fread(pc2,w/2,1,fin)<1) return(E_READ);
  879.        pc2+= c2->mwidth;
  880.      }
  881.     else SKIPr(w/2);
  882.  
  883.  
  884.    }
  885. #ifdef DEBUG
  886. fprintf(stderr,"R-Position %x\n",ftell(fin));
  887. #endif
  888.   return E_NONE;
  889.  }
  890.  
  891.  
  892. static void interpolate(implane *p)
  893. {
  894. dim w,h,x,y,yi,h2,w2;
  895. byte *optr,*nptr,*uptr;
  896.  
  897.   if ((!p) || (!p->im)) cleanup(E_INTERN);
  898.  
  899.   w=p->iwidth;
  900.   h=p->iheight;
  901.  
  902.   if(p->mwidth  < 2*w ) cleanup(E_INTERN);
  903.   if(p->mheight < 2*h ) cleanup(E_INTERN);
  904.  
  905.  
  906.   w2=p->iwidth =2*w;
  907.   h2=p->iheight=2*h;/* cut some multiplications by doing once at start */ 
  908.  
  909.  
  910.   for(y=0;y<h;y++)
  911.    {yi=h-1-y;
  912.     optr=p->im+  yi*p->mwidth + (w-1);
  913.     nptr=p->im+((yi*p->mwidth)<<1) + (w2 - 2);
  914.  
  915.     nptr[0]=nptr[1]=optr[0];
  916.  
  917.     for(x=1;x<w;x++)
  918.      { optr--; nptr-=2;
  919.        nptr[0]=optr[0];
  920.        nptr[1]=(((int)optr[0])+((int)optr[1]))>>1;
  921.      }              /* try sub divede by 2 with >>1 */    }
  922.  
  923.   for(y=0;y<h-1;y++)
  924.    {optr=p->im + ((y*p->mwidth)<<1);
  925.     nptr=optr+p->mwidth;
  926.     uptr=nptr+p->mwidth;
  927.  
  928.     for(x=0;x<w2;x++)
  929.       *(nptr++)=(((int)*(optr++))+((int)*(uptr++)))>>1;
  930.    }
  931.  
  932.   bcopy(p->im + (h2-2)*p->mwidth, p->im + (h2-1)*p->mwidth,  w2);
  933.  
  934.  }
  935.  
  936. void telltime( clock1) /* tell elapsed time, array at start is passed */
  937. unsigned long clock1[2];
  938. {
  939. unsigned long x;
  940. double t;
  941.     x=timer(clock2); /* get time I came out of it */
  942.     if( clock2[1] < clock1[1]) { /* take care of uS rollover */
  943.         clock2[1]+= 1000000L;
  944.         clock2[0]--; }
  945.         
  946.     clock2[1]-=clock1[1]; /* get diff in us */
  947.     clock2[0]-=clock1[0];
  948.     t=(double) (clock2[1]/1000000.0) +(double)clock2[0];
  949.     printf( "Loading and Decrunching Time: %8.3f Sec.  \n",t);
  950.  }
  951.  
  952. static void ycctorgb(w,h,l,c1,c2)
  953. dim w,h;
  954. implane *l,*c1,*c2;
  955. {
  956. register dim x,y,i;
  957. register  byte *pl,*pc1,*pc2;
  958.   int red,green,blue;
  959.   float L;
  960.   static int init=0;
  961.   static float XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
  962. /*
  963.   if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) cleanup(E_INTERN);
  964.   if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) cleanup(E_INTERN);
  965.   if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) cleanup(E_INTERN);
  966. */
  967.   if(do_sharp) sharpit(l);
  968.  
  969.  
  970.   if(!init)
  971.    {init=1;
  972.     for(i=0;i<256;i++)
  973.      { XL[i]=1.3584 *  ((float)i );
  974.       XC1[i]=2.2179 * (((float)i)-156.0);
  975.       XC2[i]=1.8215 * (((float)i)-137.0);
  976.       XC1g[i]= -0.194 * XC1[i];
  977.       XC2g[i]= -0.509 * XC2[i];
  978.      }
  979.    }
  980.  
  981.  
  982.  
  983.   for(y=0;y<h;y++)
  984.    {
  985.     pl =  l->im + y *  l->mwidth;
  986.     pc1= c1->im + y * c1->mwidth;
  987.     pc2= c2->im + y * c2->mwidth;
  988.  
  989.     for(x=0;x<w;x++)
  990.      {
  991.      L = XL[*pl]; 
  992.  
  993.      red  =L + XC2[*pc2];
  994.      green=L + XC1g[*pc1] + XC2g[*pc2]; 
  995.      blue =L + XC1[*pc1];
  996.  
  997.      NORM(red);
  998.      NORM(green);
  999.      NORM(blue);
  1000.  
  1001.       *(pl++ )=red; 
  1002.       *(pc1++)=/*green */ green; 
  1003.       *(pc2++)=blue;
  1004.      }
  1005.  /*   printf("line %d raw is %d %d %d \n",y,*pl,*pc1,*pc2); */
  1006.    }
  1007.  
  1008.  }
  1009.  
  1010.  
  1011. static void druckeid()
  1012. {
  1013.  struct ph1 *d;
  1014.  char ss[100];
  1015.  
  1016.  SEEK(1);
  1017.  if(READBUF<1) cleanup(E_READ);
  1018.  d=(struct ph1 *)sbuffer;
  1019.  
  1020. #define dr(feld,kennung)   \
  1021.      strncpy(ss,feld,sizeof(feld));\
  1022.      ss[sizeof(feld)]=0;\
  1023.      fprintf(stderr,"%s: %s \n",kennung,ss);
  1024.  
  1025. dr(d->id1,"Id1")
  1026. dr(d->id2,"Id2")
  1027. dr(d->id3,"Id3")
  1028. dr(d->id4,"Id4")
  1029. dr(d->id5,"Id5")
  1030.  
  1031.  
  1032. #undef dr 
  1033.  
  1034. }
  1035.  
  1036.  
  1037.  
  1038. struct pcdword
  1039.  { byte high,low;
  1040.  };
  1041.  
  1042. static int lpt[1024];
  1043.  
  1044. static void readlpt(w,h)
  1045.   dim w,h;
  1046.  {int i;
  1047.   struct pcdword *ptr;
  1048.  
  1049.   if(READBUF < 1) cleanup(E_READ);
  1050.  
  1051.   ptr = (struct pcdword *)sbuffer;
  1052.  
  1053.   for(i=0;i<( h>>2);i++,ptr++)
  1054.    {lpt[i] = ((int)ptr->high)<<8 | ptr->low ;
  1055.   /*  fprintf(stderr,"Lpt  %4d : %6d\n",i,lpt[i]);*/
  1056.    }
  1057.  
  1058. }
  1059.  
  1060.  
  1061.  
  1062. struct pcdquad { byte len,highseq,lowseq,key;};
  1063. struct pcdhqt  { byte entries; struct pcdquad entry[256];};
  1064. struct myhqt { unsigned long seq,mask,len; byte key; };
  1065.  
  1066.  
  1067. #define E ((unsigned long) 1)
  1068.  
  1069.  
  1070. static void readhqtsub(source,ziel,anzahl)
  1071.   struct pcdhqt *source;
  1072.   struct myhqt *ziel;
  1073.   int *anzahl;
  1074.  {int i;
  1075.   struct pcdquad *sub;
  1076.   struct myhqt *help;
  1077.   *anzahl=source->entries+1;
  1078.  
  1079.   for(i=0;i<*anzahl;i++)
  1080.    {sub= source->entry+i;
  1081.     help=ziel+i;
  1082.  
  1083.     help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
  1084.     help->len = ((unsigned long) sub->len) +1;
  1085.  
  1086.     if(help->len > 16) cleanup(E_HUFF);
  1087.  
  1088.     help->key = sub->key;
  1089.     help->mask = ~ ( (E << (32-help->len)) -1); 
  1090.  
  1091.   }
  1092. #ifdef DEBUG
  1093.   for(i=0;i<*anzahl;i++)
  1094.    {help=ziel+i;
  1095.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  1096.         i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
  1097.         help->seq & (~help->mask));
  1098.    }
  1099. #endif
  1100.  
  1101. }
  1102.  
  1103. static struct myhqt myhuffl[256],myhuff1[256],myhuff2[256];
  1104. static int          myhufflenl=0,myhufflen1=0,myhufflen2=0;
  1105.  
  1106. static void readhqt(w,h,n)
  1107.   dim w,h,n;
  1108.  {
  1109.   struct pcdhqt *ptr; /* fix type to placate compiler 3-6-93 */
  1110.  
  1111.   if(READBUF < 1) cleanup(E_READ);
  1112.   ptr = (struct pcdhqt *) sbuffer;
  1113.  
  1114.   readhqtsub(ptr,myhuffl,&myhufflenl);
  1115.  
  1116.   if(n<2) return;
  1117.   ptr+= 1 + 4* myhufflenl;
  1118.   readhqtsub(ptr,myhuff1,&myhufflen1);
  1119.  
  1120.   if(n<3) return;
  1121.   ptr+= 1 + 4* myhufflen1;
  1122.   readhqtsub(ptr,myhuff2,&myhufflen2);
  1123.  
  1124. }
  1125.  
  1126.  
  1127. #define nextbuf  {  nptr=sbuffer;  if(READBUF < 1) cleanup(E_READ); }
  1128. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  1129. #define shiftout(n){ sreg<<=n; inh-=n; \
  1130.                      while (inh<=24) \
  1131.                       {checkbuf; \
  1132.                        sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
  1133.                        inh+=8;\
  1134.                       }\
  1135.                     }  
  1136.  
  1137. /* I think the following routine is screwed since it works OK up to
  1138.    its usage 3/8/93 readhqt not called anymire */
  1139.    
  1140.  
  1141.  
  1142. static void decompress(w,h,f,f1,f2)
  1143.   dim w,h;
  1144.   implane *f,*f1,*f2;
  1145.  {int i,htlen,sum;
  1146.   unsigned long sreg,maxwidth;
  1147.   unsigned int inh,n,zeile,segment,ident;
  1148.   struct myhqt *htptr,*hp;
  1149.   
  1150.   byte *nptr;
  1151.   byte *lptr;
  1152.  
  1153.  
  1154.  
  1155.   if((!f) || (!f->im)) cleanup(E_INTERN);
  1156.   if((f->iheight < h) || (f->iwidth<w)) cleanup(E_INTERN);
  1157.   maxwidth=f->mwidth;
  1158.   sreg=0x0000;
  1159.   nextbuf;
  1160.   inh=32;
  1161.   lptr=0;
  1162.   shiftout(16);
  1163.   shiftout(16); 
  1164.  
  1165.   n=0;
  1166.   for(;;)
  1167.    {
  1168.     if((sreg & 0xffffff00) == 0xfffffe00)
  1169.      {shiftout(24);
  1170.       ident=sreg>>16;
  1171.       shiftout(16);
  1172.  
  1173.       zeile=(ident>>1) & 0x1fff;
  1174.       segment=ident>>14;
  1175.  
  1176. #ifdef DEBUG
  1177.       fprintf(stderr,"Ident %4x Zeile:  %6d  Segment %3d Pixels bisher: %d\n",
  1178.           ident,zeile,segment,n);
  1179. #endif
  1180.       if(lptr && (n!=maxwidth)) cleanup(E_SEQ1);
  1181.       n=0;
  1182.  
  1183.  
  1184.       if(zeile==h) return;
  1185.       if(zeile > h) cleanup(E_SEQ2);
  1186.  
  1187.       switch(segment)
  1188.        {
  1189.         case 0: if(!f) cleanup(E_SEQ7);
  1190.                 lptr=f->im + zeile*f->mwidth;
  1191.                 maxwidth=f->iwidth;
  1192.                 htlen=myhufflenl;
  1193.                 htptr=myhuffl;
  1194.                 break;
  1195.  
  1196.         case 2: if(!f1) cleanup(E_SEQ7);
  1197.                 lptr=f1->im + (zeile>>1)*f1->mwidth;
  1198.                 maxwidth=f1->iwidth;
  1199.                 htlen=myhufflen1;
  1200.                 htptr=myhuff1;
  1201.                 break;
  1202.  
  1203.         case 3: if(!f2) cleanup(E_SEQ7);
  1204.                 lptr=f2->im + (zeile>>1)*f2->mwidth;
  1205.                 maxwidth=f2->iwidth;
  1206.                 htlen=myhufflen2;
  1207.                 htptr=myhuff2;
  1208.                 break;
  1209.  
  1210.         default:cleanup(E_SEQ3);
  1211.     }
  1212.      }
  1213.     else
  1214.      {
  1215. /*      if((!lptr) || (n>maxwidth)) cleanup(E_SEQ4);*/
  1216.       if(!lptr)      cleanup(E_SEQ6);
  1217.       if(n>maxwidth) cleanup(E_SEQ4);
  1218.       for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
  1219.       if(i>=htlen) cleanup(E_SEQ5);
  1220.  
  1221.       sum=((int)(*lptr)) + ((int)hp->key);
  1222.  /*     NORM(sum); */
  1223.       *(lptr++) = sum & 0xff ;
  1224.         /* ---THIS SEEMS TO HAVE FIXED THE PROBLEM,
  1225.             BAZZ 3-10-93! CHANGING NORM TO & 0XFF ; */
  1226.       n++; 
  1227.       shiftout(hp->len);
  1228.  
  1229.      }
  1230.  
  1231.    }
  1232.  
  1233.  
  1234.  
  1235.  }
  1236.  
  1237.  
  1238.  
  1239.  
  1240. static void clear(l,n)
  1241.   implane *l;
  1242.   int n;
  1243. { dim x,y;
  1244.   byte *ptr;
  1245. /*  l->iwidth=l->mwidth;
  1246.   l->iheight=l->mheight;
  1247. */
  1248.   ptr=l->im;
  1249.   for (x=0;x<l->mwidth;x++)
  1250.     for (y=0; y<l->mheight;y++)
  1251.       *(ptr++)=n;
  1252. }
  1253.  
  1254.  
  1255. static void sharpit(l)
  1256.   implane *l;
  1257.  {int x,y,h,w,mw,akk;
  1258.   byte f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
  1259.  
  1260.   if((!l) || (!l->im)) cleanup(E_INTERN);
  1261.   if(l->iwidth > slen) cleanup(E_INTERN);
  1262.  
  1263.   old=f1; akt=f2;
  1264.   h=l->iheight;
  1265.   w=l->iwidth;
  1266.   mw=l->mwidth;
  1267.  
  1268.   for(y=1;y<h-1;y++)
  1269.    {
  1270.     ptr=l->im+ y*mw;
  1271.     optr=ptr-mw;
  1272.     work=akt;
  1273.  
  1274.     *(work++)= *(ptr++);
  1275.     for(x=1;x<w-1;x++)
  1276.      {  akk = 5*((int)ptr[0])- ((int)ptr[1])  - ((int)ptr[-1]) 
  1277.                               - ((int)ptr[mw]) - ((int)ptr[-mw]);
  1278.         NORM(akk);
  1279.         *(work++)=akk;
  1280.         ptr++;
  1281.      }
  1282.  
  1283.     *(work++)= *(ptr++);
  1284.  
  1285.     if(y>1) bcopy(old,optr,w);
  1286.     help=old;old=akt;akt=help;
  1287.      
  1288.    }
  1289.  
  1290.   bcopy(old,optr+mw,w);
  1291.  }
  1292.  
  1293. int Display_Mode_Check (void)
  1294. { /* see if we are in high res */
  1295.    struct MonitorInfo MonitorInfo;
  1296.    DisplayInfoHandle Handle;
  1297.    ULONG ModeID;
  1298.    LONG Result;
  1299.  
  1300.     GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library",36L);
  1301.     if (GfxBase==NULL) return (TRUE);
  1302.     IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library",0L);
  1303.     if (IntuitionBase==NULL)
  1304.         { CloseLibrary ((struct Library *)GfxBase);
  1305.           return (TRUE);
  1306.         }
  1307.     ModeID = GetVPModeID (&IntuitionBase->FirstScreen->ViewPort);
  1308.     Handle = FindDisplayInfo (ModeID);
  1309.     Result = GetDisplayInfoData (Handle,(UBYTE *)&MonitorInfo,
  1310.             sizeof (struct MonitorInfo),DTAG_MNTR,NULL);
  1311.  
  1312.     /*  If line frequency if >15Khz, a backdrop
  1313.      * cannot be displayed.
  1314.      */
  1315.  
  1316.     if (MonitorInfo.TotalColorClocks<220)
  1317.         { CloseLibrary ((struct Library *)GfxBase);
  1318.           CloseLibrary ((struct Library *)IntuitionBase);
  1319.           return (FALSE);
  1320.         }
  1321.     CloseLibrary ((struct Library *)GfxBase);
  1322.     CloseLibrary ((struct Library *)IntuitionBase);
  1323.     return (TRUE);
  1324. }
  1325.  
  1326.